package com.jinbei.restController;

import com.alibaba.fastjson.JSONObject;
import com.jinbei.common.Enum.ConstantsEnum;
import com.jinbei.common.annotation.AuthorAnnotation;
import com.jinbei.common.base.ResponseBase;
import com.jinbei.common.base.ResponseBaseEntity;
import com.jinbei.common.contants.Contants;
import com.jinbei.common.util.AuthorizationUtil;
import com.jinbei.common.util.CaptchaUtil;
import com.jinbei.common.util.CookieUtil;
import com.jinbei.common.util.MD5Util;
import com.jinbei.domain.User;
import com.jinbei.service.UserService;
import com.jinbei.task.CacheRunner;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author
 * 系统登录 restful 接口
 * Created by zflu on 2018/7/8.
 */
@RestController
@RequestMapping("/login")
public class LoginController extends ResponseBaseEntity{

    private final Logger logger = LoggerFactory.getLogger(LoginController.class);

    private final Map<String,Integer> map = new ConcurrentHashMap();

    private final Integer ERROR_NUM_LOCK = 5;

    private final Integer ERROR_NUM = 3;

    private static Map<String,String> mapCode = new ConcurrentHashMap();

    @Autowired
    private UserService userService;

    /**
     * @author zflu
     * @Description   用户系统登录
     * @date 2018/7/10 10:58
     * @param user, imageCode, request, response
     * @return com.jinbei.common.base.ResponseBase
     */
    @AuthorAnnotation( logs = "系统登录" , flag = false)
    @PostMapping(value = "/")
    public ResponseBase loginSystem(@RequestBody User user
            ,@RequestParam("imageCode") String imageCode
            ,HttpServletRequest request
            ,HttpServletResponse response){
        //获取验证码code
        String code = mapCode.get(request.getRemoteAddr());
        String loginName = user.getLoginName();
        String password = user.getPassword();
        if(StringUtils.isBlank(code)
                || StringUtils.isBlank(imageCode)
                || !code.toLowerCase().equals(imageCode.toLowerCase())){
            //验证码错误
            return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_102);
        }
        if(StringUtils.isBlank(loginName) || StringUtils.isBlank(password)){
            //账号或密码为空
            return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_104);
        }
        try {
            User queryUser = userService.queryUserByLoginName(loginName);
            if(queryUser == null){
                //账号或密码错误
                return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_103);
            }
            //账号被锁定
            Integer userId = queryUser.getUserId();
            boolean b = CacheRunner.cacheMap.containsKey(String.valueOf(userId));
            if(b){
                return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_105);
            }
            //获取登录失败次数
            String errorUser = CookieUtil.getCookie(request, Contants.LOGIN_ERROR_USER);
            Integer num = null;
            if(StringUtils.isNotBlank(errorUser)){
                num = map.get(errorUser);
            }
            User resultUser = userService.queryLoginUser(loginName, password);
            //密码错误
            if(resultUser == null){
                if(num != null){
                    num++;
                    map.put(loginName,num);
                    if(ERROR_NUM_LOCK.equals(num)){
                        //超过5次锁定用户
                        userService.lockOrUnLockUser(userId);
                    }
                }else{
                    map.put(loginName,1);
                    CookieUtil.addCookie(Contants.LOGIN_ERROR_USER,loginName,null,Contants.COOKIE_USER_TIME,response);
                }
                //3次错误，提示用户
                if(ERROR_NUM.equals(num)){
                    return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_103_);
                }
                //账号或密码错误
                return ResponseBaseEntity.setResultError(ConstantsEnum.Login_Error_103);
            }else{
                //移除锁定相关
                map.remove(loginName);
                CookieUtil.removeCookie(Contants.LOGIN_ERROR_USER,request,response);

                //authorization 授权码 有效期12小时
                String _password =  MD5Util.MD5(password) + Contants.DECODER_KEY;
                String authorCode = AuthorizationUtil.getAuthorization(loginName,_password);
                CookieUtil.addCookie(Contants.AUTHORIZATION,authorCode,null,Contants.COOKIE_USER_TIME,response);
                JSONObject json = new JSONObject();
                json.put(Contants.AUTHORIZATION,authorCode);
                return ResponseBaseEntity.setResultSuccess(json);
            }
        }catch (Exception e){
            logger.error("登录查询用户失败!  {}",e);
            return ResponseBaseEntity.setResultError(ConstantsEnum.ERROR_500);
        }
    }

    /**
     * @author zflu
     * @Description   系统退出登录
     * @date 2018/7/11 15:09
     * @param request
     * @return com.jinbei.common.base.ResponseBase
     */
    @AuthorAnnotation( logs = "系统退出" , flag = false)
    @GetMapping("/out")
    public ResponseBase loginOutSystem(HttpServletRequest request,
                                       HttpServletResponse response ){
        //清除授权cookie
        CookieUtil.removeCookie(Contants.AUTHORIZATION,request,response);
        return ResponseBaseEntity.setResultError(ConstantsEnum.SUCCESS_200);
    }


    /**
     * @Author zflu
     * @Description 登陆页面验证码
     * @Date 2018/7/8 14:59
     * @Param [request, response]
     * @return void
     **/
    @RequestMapping("/checkImage")
    public void createCode(HttpServletRequest request, HttpServletResponse response) throws IOException {
        // 通知浏览器不要缓存
        response.setHeader("Expires", "-1");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "-1");
        CaptchaUtil util = CaptchaUtil.Instance();
        // 将验证码输入到cookie中，用来验证
        String code = util.getString();
        String ip = request.getRemoteAddr();
        mapCode.put(ip,code);
        // 输出打web页面
        ImageIO.write(util.getImage(),Contants.IMAGE_JPG, response.getOutputStream());
    }


}
